package org.linlinjava.litemall.admin.util;

import org.springframework.util.StringUtils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DateUtil {
    public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    /**
     * 英文
     */
    public static final String DD_MMM_YYYY = "dd MMM yyyy";


    /**
     *  日期转字符串
     * @param dateTime
     * @return
     */
    public static String dateToString(LocalDateTime dateTime){
        return dateToString(dateTime, YYYY_MM_DD_HH_MM_SS);
    }
    /**
     *  日期转字符串
     * @param dateTime
     * @param pattern
     * @return
     */
    public static String dateToString(LocalDateTime dateTime, String pattern){
        if(null == dateTime){
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return dateTime.format(formatter);
    }
    public static LocalDateTime parseISOZDateTime(String timeStr) {
        if (timeStr == null || timeStr.isEmpty()) {
            return null;
        }
        OffsetDateTime odt = OffsetDateTime.parse(timeStr);
        return odt.atZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     *
     * 字符串转日期
     * @param dateTimeStr
     * @return
     */
    public static LocalDateTime stringToDate(String dateTimeStr){
        return stringToDate(dateTimeStr, YYYY_MM_DD_HH_MM_SS);
    }
    /**
     *
     * 字符串转日期
     * @param dateTimeStr
     * @param pattern
     * @return
     */
    public static LocalDateTime stringToDate(String dateTimeStr, String pattern){
        if(StringUtils.isEmpty(dateTimeStr)){
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.parse(dateTimeStr, formatter);
    }

    /**
     * JDK8获取一段时间范围内符合星期几的日期集合
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param workDate  周几 1,2,3,4
     */
    public static List<LocalDate> getMeetDayOfWeekLocalDates(java.time.LocalDate startDate, java.time.LocalDate endDate, Integer[] workDate) {

        List<DayOfWeek> dayOfWeeks = Arrays.stream(workDate)
                .map(DayOfWeek::of)
                .collect(Collectors.toList());

        long distance = ChronoUnit.DAYS.between(startDate, endDate);

        return Stream.iterate(startDate, d -> d.plusDays(1))
                .limit(distance + 1)
                .filter(localDate -> dayOfWeeks.contains(localDate.getDayOfWeek()))
                .collect(Collectors.toList());
    }


    public static List<LocalDate> getMeetDayOfMonthLocalDates(java.time.LocalDate startDate, java.time.LocalDate endDate, Integer[] workDate) {
//         MonthDay
        List<Integer> codesInteger = Arrays.stream(workDate).collect(Collectors.toList());

        long distance = ChronoUnit.DAYS.between(startDate, endDate);

        return Stream.iterate(startDate, d -> d.plusDays(1))
                .limit(distance + 1)
                .filter(localDate -> {
                    boolean flag = false;
                    for (int i = 0; i < codesInteger.size(); i++) {
                        if(localDate.getDayOfMonth() == codesInteger.get(i)){
                            flag =  true;
                            break;
                        }
                    }
                    return flag;
                }).collect(Collectors.toList());
    }

    public static List<LocalDate> getMeetDayOfYearDates(String[] days) {
         List<LocalDate> daysOfYear = Arrays.stream(days).map(day -> {
             String[] ds = day.split("-");
             return LocalDate.of(Integer.valueOf(ds[0]),Integer.valueOf(ds[1]),Integer.valueOf(ds[2]));
         }).collect(Collectors.toList());
         return daysOfYear;
    }

    public static List<LocalDate> getMeetDaysOfDays(java.time.LocalDate startDate, java.time.LocalDate endDate){

        long distance = ChronoUnit.DAYS.between(startDate, endDate);

        return Stream.iterate(startDate, d -> d.plusDays(1))
                .limit(distance + 1)
                .collect(Collectors.toList());
    }

}
